package com.dragon.modules.yuegou.service.impl.act;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragon.modules.yuegou.entity.act.GiftGoodsRefEntity;
import com.dragon.modules.yuegou.entity.act.GiftRecordEntity;
import com.dragon.modules.yuegou.entity.product.SkuEntity;
import com.dragon.modules.yuegou.entity.product.SpuEntity;
import com.dragon.modules.yuegou.enums.OwnerType;
import com.dragon.modules.yuegou.enums.coupon.CouponPlatform;
import com.dragon.modules.yuegou.enums.coupon.CouponSourceType;
import com.dragon.modules.yuegou.enums.order.OrderBuyerType;
import com.dragon.modules.yuegou.enums.order.OrderType;
import com.dragon.modules.yuegou.enums.points.DetailIncomeExpenses;
import com.dragon.modules.yuegou.enums.points.DetailSource;
import com.dragon.modules.yuegou.enums.points.DetailType;
import com.dragon.modules.yuegou.enums.product.SpuPublishStatus;
import com.dragon.modules.yuegou.mapper.act.GiftRecordMapper;
import com.dragon.modules.yuegou.model.act.Gift;
import com.dragon.modules.yuegou.model.act.GiftGoodsRef;
import com.dragon.modules.yuegou.model.act.GiftRecord;
import com.dragon.modules.yuegou.model.coupon.Coupon;
import com.dragon.modules.yuegou.model.order.Order;
import com.dragon.modules.yuegou.model.order.OrderPay;
import com.dragon.modules.yuegou.model.points.Detail;
import com.dragon.modules.yuegou.model.product.Sku;
import com.dragon.modules.yuegou.query.act.GiftGoodsRefQuery;
import com.dragon.modules.yuegou.query.product.SkuQuery;
import com.dragon.modules.yuegou.service.act.GiftGoodsRefService;
import com.dragon.modules.yuegou.service.act.GiftRecordService;
import com.dragon.modules.yuegou.service.coupon.CouponService;
import com.dragon.modules.yuegou.service.order.OrderService;
import com.dragon.modules.yuegou.service.points.DetailService;
import com.dragon.modules.yuegou.service.product.SkuService;
import com.dragon.modules.yuegou.service.product.SpuService;
import com.dragon.modules.yuegou.service.product.StockService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 注册会员送礼记录表 服务实现
 *
 * @author pbuilder generated
 * @version 2.0
 * @date 2019-11-19 19:34:06
 */
@Slf4j
@Service("actGiftRecordService")
public class GiftRecordServiceImpl
        extends ServiceImpl<GiftRecordMapper, GiftRecordEntity>
        implements GiftRecordService {


    @Autowired
    private CouponService couponService;

    @Autowired
    private SkuService skuService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private DetailService detailService;

    @Autowired
    private SpuService spuService;

    @Autowired
    private GiftGoodsRefService giftGoodsRefService;

    @Autowired
    private StockService stockService;

    @Override
    public void givePoints(List<Gift> gifts, String memberId, DetailSource detailSource) {
        if (gifts.size() < 1) {
            return;
        }
        for (int i = 0; i < gifts.size(); i++) {
            try {
                givePoint(gifts.get(i),memberId,detailSource);
            } catch (Exception e) {
                log.debug("赠送积分失败礼物id={}，错误信息{}",gifts.get(i),e.getMessage());
            }
            gifts.remove(gifts.get(i));
            i= i-1;
        }
    }

    @Override
    public void giveCommoditys(List<Gift> gifts, String memberId) {
        if (gifts.size() < 1) {
            return;
        }
        for (int i = 0; i < gifts.size(); i++) {
            try {
                this.giveCommodity(gifts.get(i),memberId);
            } catch (Exception e) {
                log.debug("赠送商品失败礼物id={}，错误信息{}",gifts.get(i),e.getMessage());
            }
            gifts.remove(gifts.get(i));
            i= i-1;
        }
    }

    @Override
    public void givePackage(List<Gift> gifts, String memberId) {
        if (gifts.size() < 1) {
            return;
        }
        for (int i = 0; i < gifts.size(); i++) {
            try {
                this.givePackageItem(gifts.get(i),memberId);
            } catch (Exception e) {
                log.debug("赠送套餐失败礼物id={}，错误信息{}",gifts.get(i),e.getMessage());
            }
            gifts.remove(gifts.get(i));
            i= i-1;
        }
    }

    private void givePackageItem(Gift gift, String memberId) {
        GiftGoodsRefQuery refQuery = new GiftGoodsRefQuery();
        refQuery.setGiftId(gift.getId());
        refQuery.setDel(false);
        List<GiftGoodsRefEntity> list = giftGoodsRefService.list(refQuery.toQueryWrapper());
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        // 创建订单
        Order orderRequest = new Order();// 准备OrderRequest
        orderRequest.setType(OrderType.MEAL);
        orderRequest.setBusdId(gift.getBusdId());
        orderRequest.setBuyerId(memberId);
        orderRequest.setBuyerType(OrderBuyerType.MEMBER);
        BigDecimal sum = BigDecimal.ZERO;

        for (GiftGoodsRefEntity ref : list) {
            SpuEntity spu = spuService.getById(ref.getArticleId());
            if (SpuPublishStatus.UPPER.equals(spu.getPublishStatus())
                    || (Objects.nonNull(spu.getEndTime()) && spu.getEndTime().isBefore(LocalDateTime.now()))) {
                return;
            }
            SkuQuery query = new SkuQuery();
            query.setSpuId(spu.getId());
            query.del().eq(false);
            List<SkuEntity> skuList = skuService.list(query.toQueryWrapper());
            if (CollectionUtils.isEmpty(skuList)) {
                return;
            }
            Sku sku = new Sku(skuList.get(0));
            Integer stock = stockService.getStockBySkuId(sku.getId());
            if (stock < ref.getQuantity()) {
                continue;
            }
            orderRequest.addItem(sku.getId(), ref.getQuantity());
            sum = sum.add((sku.getDiscountPrice().multiply(new BigDecimal(ref.getQuantity()))));
        }
        if (CollectionUtils.isEmpty(orderRequest.getOrderItemList())){
            return;
        }
        Order order = orderService.issueOrder(orderRequest);
        orderRequest.setCouponAmount(sum);// 优惠金额

        OrderPay orderPay = new OrderPay();
        orderPay.setOrderNo(order.getId());
        orderPay.setPayTime(LocalDateTime.now());
        orderPay.setPayCash(order.getPayableAmount());
        orderService.payZeroOrder(orderPay);
        createGiftRecord(memberId,gift,order.getId(),null);
    }

    @Override
    public void giveParkCoupons(List<Gift> gifts, String memberId) {
        if (gifts.size() < 1) {
            return;
        }
        for (int i = 0; i < gifts.size(); i++) {
            try {
                this.giveParkCoupon(gifts.get(i),memberId);
            } catch (Exception e) {
                log.debug("赠送停车券失败礼物id={}，错误信息{}",gifts.get(i),e.getMessage());
            }
            gifts.remove(gifts.get(i));
            i= i-1;
        }
    }

    @Override
    public void giveDiscountCoupons(List<Gift> gifts, String memberId) {
        if (gifts.size() < 1) {
            return;
        }
        for (int i = 0; i < gifts.size(); i++) {
            try {
                giveDiscountCoupon(gifts.get(i),memberId);
            } catch (Exception e) {
                log.debug("赠送优惠券失败礼物id={}，错误信息{}",gifts.get(i),e.getMessage());
            }
            gifts.remove(gifts.get(i));
            i= i-1;
        }
    }

    private void giveDiscountCoupon(Gift gift, String memberId) {
        String giftId = gift.getId();
        GiftGoodsRefQuery query = new GiftGoodsRefQuery();
        query.setDel(false);
        query.setGiftId(giftId);
        List<GiftGoodsRefEntity> list = giftGoodsRefService.list(query.toQueryWrapper());
        if (CollectionUtils.isNotEmpty(list)) {
            Map<String, List<GiftGoodsRefEntity>> map = list.stream().collect(Collectors.groupingBy(GiftGoodsRefEntity::getArticleId));
            for (String articleId : map.keySet()) {
                List<GiftGoodsRefEntity> refs = map.get(articleId);
                Integer sum = refs.stream().map(GiftGoodsRefEntity::getQuantity).reduce(Integer::sum).orElse(0);
                if (sum <= 0) {
                    continue;
                }
                for (Integer i = 0; i < sum; i++) {
                    Coupon coupon = couponService.createCoupon(null, memberId, articleId, CouponSourceType.WELFARE);
                    createGiftRecord(memberId,gift,coupon.getId(),null);
                }
            }
        }
    }

    /***
     * 赠送积分
     * @param gift
     * @param memberId
     */
    public void givePoint(Gift gift, String memberId,DetailSource source) {
        Detail detail = new Detail();
        detail.setBusdId(gift.getBusdId());
        detail.setMemberId(memberId);
        detail.setType(DetailType.SIGN);

        detail.setSource(source);
        detail.setIncomeExpenses(DetailIncomeExpenses.INCOME);
        detail.setType(DetailType.REGISTER);
        GiftGoodsRefQuery query = new GiftGoodsRefQuery();
        query.setDel(false);
        query.setGiftId(gift.getId());
        List<GiftGoodsRefEntity> list = giftGoodsRefService.list(query.toQueryWrapper());
        Integer sum = list.stream().map(a -> a.getArticlePoints() * a.getQuantity()).reduce(Integer::sum).orElse(0);
        detail.setPoints(sum);
        detailService.pointANS(detail);
        if (Objects.nonNull(source)) {
            createGiftRecord(memberId,gift,"",null);
        }
    }

    /***
     * 赠送商品
     * @param gift
     * @param memberId
     */
    private void giveCommodity(Gift gift, String memberId) {
        GiftGoodsRefQuery refQuery = new GiftGoodsRefQuery();
        refQuery.setGiftId(gift.getId());
        refQuery.setDel(false);
        List<GiftGoodsRefEntity> list = giftGoodsRefService.list(refQuery.toQueryWrapper());
        gift.setRefs(list.stream().map(GiftGoodsRef::new).collect(Collectors.toList()));
        // 创建订单
        Order orderRequest = new Order();// 准备OrderRequest
        orderRequest.setType(OrderType.BUY);
        orderRequest.setBusdId(gift.getBusdId());
        orderRequest.setBuyerId(memberId);
        orderRequest.setBuyerType(OrderBuyerType.MEMBER);
        BigDecimal sum = BigDecimal.ZERO;
        if (CollectionUtils.isNotEmpty(list)) {
            for (GiftGoodsRefEntity ref : list) {
                String articleId = ref.getArticleId();
                SkuEntity sku = skuService.getById(articleId);
                if (Objects.isNull(sku)) {
                    return;
                }
                SpuEntity spu = spuService.getById(sku.getSpuId());
                if (SpuPublishStatus.UPPER.equals(spu.getPublishStatus())
                        || (Objects.nonNull(spu.getEndTime()) && spu.getEndTime().isBefore(LocalDateTime.now()))) {
                    return;
                }
                orderRequest.addItem(articleId, ref.getQuantity());
                sum = sum.add((sku.getDiscountPrice().multiply(new BigDecimal(ref.getQuantity()))));
            }
            Order order = orderService.issueOrder(orderRequest);
            orderRequest.setCouponAmount(sum);// 优惠金额

            OrderPay orderPay = new OrderPay();
            orderPay.setOrderNo(order.getId());
            orderPay.setPayTime(LocalDateTime.now());
            orderPay.setPayCash(order.getPayableAmount());
            orderService.payZeroOrder(orderPay);
            createGiftRecord(memberId,gift,order.getId(),null);
        }

    }



    /***
     * 赠送停车券
     * @param gift
     * @param memberId
     */

    private void giveParkCoupon(Gift gift, String memberId) {
        //给注册用户添加停车券
        Coupon coupon = new Coupon();
        //所有者类型是平台
        coupon.setOwnerType(OwnerType.PLATFORM);
        coupon.setBusdId(gift.getBusdId());
        coupon.setMemberId(memberId);
        coupon.setUsed(false);
        coupon.setExpired(false);
        coupon.setExpireTime(LocalDateTime.now().plusDays(1));
        coupon.setPlatform(CouponPlatform.OTHER);
        coupon.setSource("会员注册送礼");
        GiftGoodsRefQuery query = new GiftGoodsRefQuery();
        query.setGiftId(gift.getId());
        query.setDel(false);
        List<GiftGoodsRefEntity> list = giftGoodsRefService.list(query.toQueryWrapper());
        gift.setRefs(list.stream().map(GiftGoodsRef::new).collect(Collectors.toList()));
        if (CollectionUtils.isNotEmpty(list)) {
            for (GiftGoodsRefEntity ref : list) {
                coupon.setCouponTemplateId(ref.getArticleId());
                couponService.save(coupon);
                //生成注册送礼记录
                createGiftRecord(memberId, gift,coupon.getId(),ref.getArticleId());

            }
        }
    }

    /**
     * 创建注册送礼记录
     *
     * @param memberId
     * @param gift
     */
    private void createGiftRecord(String memberId, Gift gift,String giveId,String itemId) {
        GiftRecord giftRecord = new GiftRecord();
        giftRecord.setUserId(memberId);
        giftRecord.setBusdId(gift.getBusdId());
        giftRecord.setGiftId(gift.getId());
        switch (gift.getCommodityType()) {
            case VOUCHER_COUPON:
                SkuEntity sku = skuService.getById(gift.getRefs().get(0).getArticleId());
                SpuEntity spu = spuService.getById(sku.getSpuId());
                giftRecord.setInvalidTime(spu.getEndTime());
                giftRecord.setGiveId(giveId);
                break;
            case PARK_COUPON:
                giftRecord.setInvalidTime(LocalDateTime.now().plusDays(1));
                giftRecord.setGiveId(giveId);
                giftRecord.setArticleId(itemId);
                break;
            default:
                giftRecord.setInvalidTime(null);
                break;
        }
        baseMapper.insert(giftRecord);
        log.debug("会员id={} 赠送giftId={} 成功",memberId,gift.getId());
    }
}